class Wire(name: String, isOutput: Boolean, width: Int) {  
  override def toString(): String =  {
    val tmp= "output"  +  " [ " + (width-1) + ":0] " + name
    if( isOutput) tmp
    else tmp.replaceAll("output", "input")
  }

}

class Bundle(name: String,  wires: Wire*){
  var isReverse = false
  def toString( num: Int): String ={
    val  tmp =  wires.foldLeft("")( (a,b) => a+  "\n" + b + "__" + name + num + ";")
    if( isReverse ) tmp.replaceAll("input", "zzxx").replaceAll("output","input").replaceAll("zzxx", "output")
    else tmp
  }

  def reverse(n : Int): String= { isReverse=true
    val z = toString(n)
    isReverse=false
    z
  }
  /*
  def reverse( a: Bundle): Bundle= this(true)
  def this(in: Boolean) = {
    isReverse = in
  }
  def this() = this(false)
  */
  def toStringAsWire(number: Int): String = toString(number).replaceAll("input", "wire").replaceAll("output", "wire")
}


object bundle extends App {
/*
  val w1 = new Wire("addr", true, 16)
  val w2 = new Wire("data", true, 8)
  val w3 = new Wire("resp", false, 1)
  val bundleCPU2Mem = new Bundle("bundleCPU2Mem", true, w1, w2, w3)
  */
  val bundleCPU2Mem = new Bundle("bundleCPU2Mem", 
    new Wire("addr", true, 16),
    new Wire("data", true, 8),
    new Wire("resp", false, 1)
    )

  println( bundleCPU2Mem.toString(100) )
  println( bundleCPU2Mem.reverse(100) )
// zzz println( bundleCPU2Mem ) 
println( bundleCPU2Mem.toStringAsWire(1))
println( bundleCPU2Mem.toStringAsWire(2))


/*
  val naiveTheorems = List(
    new Theorem("Seq has countably many elements"),
    new Theorem("We can choose subsequence"),
    new Theorem("There is a real/rational between two reals"),

    new Theorem("0 iff < epsilon"),
    new Theorem("Boundedness means sup and inf are reals"),
    new Theorem("Bounded infinity points has limit point"),

    new Theorem("Larger sets has bigger sup"),
    new Theorem("nothing")
  )

  naiveTheorems foreach println 

  val t1 = new Theorem("Subsequence of a bounded seq. is also ...", new Proof("proof1", 2,  naiveTheorems(6), naiveTheorems(4) ))
  println(t1)
  */

}
